package com.yonyou.pmclouds.businessobject.util;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public class SortListUtil {

    public static final String DESC = "desc";

    public static final String ASC = "asc";

    /**
     * 对list中的元素按fields和sorts进行排序,
     * fields[i]指定排序字段,sorts[i]指定排序方式.如果sorts[i]为空则默认按升序排列.
     *
     * @param list   排序组合
     * @param fields 排序字段
     * @param sorts  排序方式
     * @return 排序结果
     */
    @SuppressWarnings("unchecked")
    public static List<?> sort(List<?> list, String[] fields, String[] sorts) {
        if (fields != null && fields.length > 0) {
            for (int i = fields.length - 1; i >= 0; i--) {
                final String field = fields[i];
                String tmpSort = ASC;
                if (sorts != null && sorts.length > i && sorts[i] != null) {
                    tmpSort = sorts[i];
                }
                final String sort = tmpSort;
                Collections.sort(list, new Comparator() {
                    public int compare(Object a, Object b) {
                        int ret = 0;
                        try {
                            Field f = a.getClass().getDeclaredField(field);
                            f.setAccessible(true);
                            Class<?> type = f.getType();
                            if (type == int.class) {
                                ret = Integer.compare(f.getInt(a), f.getInt(b));
                            } else if (type == double.class) {
                                ret = Double.compare(f.getDouble(a), f.getDouble(b));
                            } else if (type == long.class) {
                                ret = Long.compare(f.getLong(a), f.getLong(b));
                            } else if (type == float.class) {
                                ret = Float.compare(f.getFloat(a), f.getFloat(b));
                            } else if (type == Date.class) {
                                ret = ((Date) f.get(a)).compareTo((Date) f.get(b));
                            } else if (isImplementsOf(type, Comparable.class)) {
                                ret = ((Comparable) f.get(a)).compareTo(f.get(b));
                            } else {
                                ret = String.valueOf(f.get(a)).compareTo(String.valueOf(f.get(b)));
                            }
                        } catch (SecurityException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
                            e.printStackTrace();
                        }
                        if (sort != null && sort.toLowerCase().equals(DESC)) {
                            return -ret;
                        } else {
                            return ret;
                        }
                    }
                });
            }
        }
        return list;
    }

    public static List<?> sort(List<?> list, String fields, String sorts) {
        String[] sortFields = fields.split(",");
        String[] sortWays = sorts.split(",");
        return sort(list, sortFields, sortWays);
    }

    /**
     * 判断对象实现的所有接口中是否包含szInterface
     */
    private static boolean isImplementsOf(Class<?> clazz, Class<?> szInterface) {
        boolean flag = false;
        Class<?>[] face = clazz.getInterfaces();
        for (Class<?> c : face) {
            flag = c == szInterface || isImplementsOf(c, szInterface);
        }
        if (!flag && null != clazz.getSuperclass()) {
            return isImplementsOf(clazz.getSuperclass(), szInterface);
        }
        return flag;

    }
}
